package com.lhy.mymall.controller;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.lhy.mymall.common.ApiRestResponse;
import com.lhy.mymall.common.Constant;
import com.lhy.mymall.exception.ExceptionEnum;
import com.lhy.mymall.exception.MallException;
import com.lhy.mymall.flter.UserJWTFilter;
import com.lhy.mymall.pojo.User;
import com.lhy.mymall.service.EmailService;
import com.lhy.mymall.service.UserService;
import com.lhy.mymall.utils.EmailUtil;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.Date;

/**
 * @author: 卢辉宇
 * @date: 2022/12/2 21:18
 * @description:
 */

@RestController
public class UserController {

    @Resource
    UserService userService;

    @Resource
    EmailService emailService;

    @PostMapping("/admin/test/t")
    public String filterTest() {
        return "测试通过";
    }

    /**
     * 用户注册
     * @param username
     * @param password
     * @param emailAddress
     * @param verificationCode  先调用sendEmail()方法获取验证码
     * @return
     * @throws MallException
     */
    @PostMapping("/register")
    public ApiRestResponse register(@RequestParam("username") String username, @RequestParam("password") String password, @RequestParam("emailAddress") String emailAddress, @RequestParam("verificationCode") String verificationCode) throws MallException {
        /*先进行校验*/
        /*判断用户名是否为空*/
        if (!StringUtils.hasText(username)) {
            /*返回在枚举类型定义的用户名为空的枚举*/
            return ApiRestResponse.error(ExceptionEnum.NEED_USER_NAME);
        }
        if (!StringUtils.hasText(password)) {
            return ApiRestResponse.error(ExceptionEnum.NEED_PASSWORD);
        }
        /*密码长度的校验*/
        if (password.length() < 8) {
            return ApiRestResponse.error(ExceptionEnum.PASSWORD_TOO_SHORT);
        }
        if (!StringUtils.hasText(emailAddress)) {
            return ApiRestResponse.error(ExceptionEnum.NEED_EMAIL_ADDRESS);
        }
        if (!StringUtils.hasText(verificationCode)) {
            return ApiRestResponse.error(ExceptionEnum.NEED_VERIFICATION_CODE);
        }

        //检查邮箱是否已注册
        boolean registered = userService.checkEmailRegistered(emailAddress);
        if (registered) {
            //已注册
            return ApiRestResponse.error(ExceptionEnum.EMAIL_ALREADY_BEEN_REGISTERED);
        }

        //检查验证码是否与redission的一致。。。
        boolean passEmailAndCode = emailService.checkEmailAndCode(emailAddress, verificationCode);
        if (!passEmailAndCode) {
            //验证码不匹配
            return ApiRestResponse.error(ExceptionEnum.WRONG_VERIFICATION_CODE);
        }

        /*开始注册*/
        userService.register(username, password, emailAddress);
        return ApiRestResponse.success();
    }


    /**
     * 登录模块
     *
     * @param username
     * @param password
     * @param session
     * @return
     */
    @PostMapping("/login")
    public ApiRestResponse login(String username, String password,@RequestParam String verificationCode, HttpSession session) throws MallException {
        /*先进行校验*/
        /*判断用户名是否为空*/
        if (!StringUtils.hasText(username)) {
            /*返回在枚举类型定义的用户名为空的枚举*/
            return ApiRestResponse.error(ExceptionEnum.NEED_USER_NAME);
        }
        if (!StringUtils.hasText(password)) {
            return ApiRestResponse.error(ExceptionEnum.NEED_PASSWORD);
        }
        if (!StringUtils.hasText(verificationCode)) {
            return ApiRestResponse.error(ExceptionEnum.NEED_VERIFICATION_CODE);
        }

        /*开始处理登录业务*/
        User user = userService.login(username, password, verificationCode);
        //保存用户时将密码抹除
        user.setPassword(null);
        //保存到session
        session.setAttribute(Constant.MALL_USER, user);
        return ApiRestResponse.success(user);
    }

    @PostMapping("/user/update")
    public ApiRestResponse updateSignature(HttpSession session, @RequestParam String signature) throws MallException {
//        /*获取session的用户对象*/
//        User currentUser = (User) session.getAttribute(Constant.MALL_USER);
//        if (currentUser == null) {
//            return ApiRestResponse.error(ExceptionEnum.NEED_LOGIN);
//        }

        User currentUser = UserJWTFilter.currentUser;

        /*更新用户数据*/
        User user = new User();
        user.setId(currentUser.getId());
        user.setPersonalizedSignature(signature);

        //插入数据库
        userService.updateSignature(user);
        return ApiRestResponse.success();
    }

    @PostMapping("/user/logout")
    public ApiRestResponse logout(HttpSession session) {
        session.removeAttribute(Constant.MALL_USER);
        return ApiRestResponse.success();
    }

    /**
     * 管理员登录模块
     *
     * @param username
     * @param password
     * @param session
     * @return
     */
    @PostMapping("/adminLogin")
    public ApiRestResponse adminLogin(@RequestParam String username, @RequestParam String password,@RequestParam String verificationCode, HttpSession session) throws MallException {
        /*先进行校验*/
        /*判断用户名是否为空*/
        if (!StringUtils.hasText(username)) {
            /*返回在枚举类型定义的用户名为空的枚举*/
            return ApiRestResponse.error(ExceptionEnum.NEED_USER_NAME);
        }
        if (!StringUtils.hasText(password)) {
            return ApiRestResponse.error(ExceptionEnum.NEED_PASSWORD);
        }
        if (!StringUtils.hasText(verificationCode)) {
            return ApiRestResponse.error(ExceptionEnum.NEED_VERIFICATION_CODE);
        }

        /*开始处理登录业务*/
        User user = userService.login(username, password,verificationCode);

        /*判断是否是管理员业务*/
        if (userService.checkAdminRole(user)) {
            //是管理员
            //保存用户时将密码抹除
            user.setPassword(null);
            //保存到session
            session.setAttribute(Constant.MALL_USER, user);
        } else {
            //不是管理员
            return ApiRestResponse.error(ExceptionEnum.NEED_ADMIN);
        }

        return ApiRestResponse.success(user);
    }


    /**
     * 发邮件方法
     *
     * @param emailAddress
     * @return
     * @throws MallException
     */
    @PostMapping("/user/sendEmail")
    public ApiRestResponse sendEmail(String emailAddress) throws MallException {
        /*1.检查地址是否有效
         * 2.检查是否已注册
         * */
        boolean validEmailAddress = EmailUtil.isValidEmailAddress(emailAddress);
        if (!validEmailAddress) {
            //地址无效，返回错误码
            return ApiRestResponse.error(ExceptionEnum.WRONG_EMAIL);
        }

        /*邮件地址有效,检查是否已注册*/
        //调用service层的。。。
//        boolean registered = userService.checkEmailRegistered(emailAddress);
//        if (registered) {
//            /*email地址检查不通过*/
//            throw new MallException(ExceptionEnum.EMAIL_ALREADY_BEEN_REGISTERED);
//        }

        /*发送邮件*/
        //得到验证码
        String verificationCode = EmailUtil.genVerificationCode();
        //保存到redis...
        boolean saveEmailToRedis = emailService.saveEmailToRedis(emailAddress, verificationCode);
        if (!saveEmailToRedis) {
            //缓存中的验证码还在有效期内
            return ApiRestResponse.error(ExceptionEnum.EMAIL_ALREADY_BEEN_SEND);
        }
        //新建email的service...
//        emailService.sendSimpleMessage(emailAddress, Constant.MAIL_SUBJECT, "您的注册验证码是:" + verificationCode);
        System.out.println("验证码："+verificationCode);
        return ApiRestResponse.success();
    }

    /**
     * JWT登录模块
     *
     * @param username
     * @param password
     * @param session
     * @return
     */
    @PostMapping("/loginWithJwt")
    public ApiRestResponse loginWithJwt(String username, String password,@RequestParam String verificationCode,HttpSession session) throws MallException {
        /*先进行校验*/
        /*判断用户名是否为空*/
        if (!StringUtils.hasText(username)) {
            /*返回在枚举类型定义的用户名为空的枚举*/
            return ApiRestResponse.error(ExceptionEnum.NEED_USER_NAME);
        }
        if (!StringUtils.hasText(password)) {
            return ApiRestResponse.error(ExceptionEnum.NEED_PASSWORD);
        }
        if (!StringUtils.hasText(verificationCode)) {
            return ApiRestResponse.error(ExceptionEnum.NEED_VERIFICATION_CODE);
        }

        /*开始处理登录业务*/
        User user = userService.login(username, password, verificationCode);
        //保存用户时将密码抹除
        user.setPassword(null);

        /*保存到jwt*/
        //1.签名密匙算法
        Algorithm algorithm = Algorithm.HMAC256(Constant.JWT_KEY);
        //2.生成JWT的token,并设置信息体的内容和签名
        String token = JWT.create().
                withClaim(Constant.USER_NAME, user.getUsername())
                .withClaim(Constant.USER_ID, user.getId())
                .withClaim(Constant.USER_ROLE, user.getRole())
                //设置过期时间
                .withExpiresAt(new Date(System.currentTimeMillis() + Constant.EXPIRE_TIME))
                //用签名密匙设置签名
                .sign(algorithm);

        return ApiRestResponse.success(token);
    }
}
